#SingleInstance, Force
#Include <JSON>
#EscapeChar ``
#CommentFlag ;


Config 	:= JSON_Load(A_ScriptDir "\Config.json")
psgDesc := new CPsgDescription()



 ;{___  Load Settings from Config  _________________________________________________________________________
	
	
	for index, val in Config.Lists.IssueSources
	{
		IssueSources .= (IssueSources ? "|" : "") val
		IssueSourceCount++
	}
	IssueSourceCount := IssueSourceCount ? IssueSourceCount : 1
	 
	 
	for index, val in Config.Lists.IssueTypes
	{
		IssueTypes .= (IssueTypes ? "|" : "") val
		IssueTypeCount++
	}
	IssueTypeCount := IssueTypeCount ? IssueTypeCount : 1

	
	GuiColor 	 	:= Config.Gui.1.Color.WindowBack
	GuiTxtColor	 	:= Config.Gui.1.Color.WindowText
	ControlColor 	:= Config.Gui.1.Color.ControlBack
	ControlTxtColor := Config.Gui.1.Color.ControlText
	GuiHeight 	 	:= Config.Gui.1.Size.H
	GuiWidth 	 	:= Config.Gui.1.Size.W
	MarginX			:= Config.Gui.1.Margin.X
	MarginY			:= Config.Gui.1.Margin.Y
	GuiTitle	 	:= Config.Gui.1.Title
	FontType 	 	:= Config.Gui.1.Font.Type
	FontSize 	 	:= Config.Gui.1.Font.Size
	Version		 	:= Config.Version
	
;}


	


;{___  Main GUI ____________________________________________________________________________________________

MainGui:	
	Gui, Color, %GuiColor%, %ControlColor%
	Gui, Font, s%FontSize% c%GuiTxtColor%, %FontType%
	Gui, Margin, %MarginX%, %MarginY%
	Gui, +Resize +AlwaysOnTop -theme
	
	GuiHwnd := WinExist("A")

	; --- RTA Number ---	
	Gui, Add, Text, +BackgroundTrans  x11 y20 w190 h20,RTA Number (if exists)	
	Gui, Add, Edit, xm y+5 w165 h25 c%ControlTxtColor% +center vRtaNum hwndRtaNumHwnd,
	Gui, Add, button, x+2 yp+1 h25 w85, Search


	; --- Short Description ---
	Gui, Add, Text, +BackgroundTrans  x11 y+15 w280 h20,Short Description of Issue:
	Gui, Add, Edit, xm y+5 w275 h25 c%ControlTxtColor% vShortDescription hwndShortDescHwnd gShortDescription_Event, 

	; --- Issue Source Group ---
	Gui, Add, Text, +BackgroundTrans  x11 y+20 Section, Issue Source Group:
	Gui, Add, ListBox, xm y+5 w240 c%ControlTxtColor% r%IssueSourceCount% hwndIssueSourceHwnd vissueSource gIssueSource_Event, %IssueSources%


	; --- Issue Types ---
	Gui, Add, Text, +BackgroundTrans  x310 y20 Section,Issue Type(s)	
	Gui, Add, ListBox, xs y+5 w180 h244 c%ControlTxtColor% +multi r%IssueTypeCount% hwndIssueTypesHwnd vissueType gIssueType_Event, %IssueTypes%


	
	ListBoxW	:= 160
	ListBoxW1	:= Round(ListBoxW + 1)

	; --- Assemblies ---
	Gui, Add, Text, +BackgroundTrans x520 y20 +Section,Affected Assembly(s)	
	Gui, Add, Edit, xs y+5 w%ListBoxW% h25 -border +section c%ControlTxtColor% +hwndAssembliesHwnd vnewAsseblies,
	Gui, Add, Button, x+2 yp+1 h25 gAssembliesAdd, +
	Gui, Add, ListBox, xs-1 y+0 w%ListBoxW1% r6 c%ControlTxtColor% +AltSubmit hwndAssembliesListHwnd gAssemblies_Event,

	
	; --- Sub-Assemblies ---
	Gui, Add, Text, +BackgroundTrans  x725 y20 +Section, Sub-Assembly(s)
	Gui, Add, Edit, xs y+5 w%ListBoxW% h25 c%ControlTxtColor% +hwndSubAssembliesHwnd vnewSubAssemblies,
	Gui, Add, Button, x+2 yp+1 h25 gSubAssembliesAdd, +
	Gui, Add, ListBox, xs-1 y+0 w%ListBoxW1% r6 c%ControlTxtColor% +AltSubmit hwndSubAssembliesListHwnd gSubAssemblies_Event,


	; --- Work Orders ---
	Gui, Add, Text, +BackgroundTrans x520 y+15 +Section, WorkOrder(s)
	Gui, Add, Edit, xs y+5 w%ListBoxW% h25 c%ControlTxtColor% hwndWorkOrdersHwnd vnewWorkOrders,
	Gui, Add, Button, x+2 yp+1 h25 gWorkOrdersAdd, +
	Gui, Add, ListBox, xs-1 y+0 w%ListBoxW1% r6 c%ControlTxtColor% +AltSubmit hwndWorkOrdersListHwnd gWorkOrders_Event,


	; --- ECN numbers ---	
	Gui, Add, Text, +BackgroundTrans  x725 ys +Section,ECN Number(s)
	Gui, Add, Edit, xs y+5 w%ListBoxW% h25 c%ControlTxtColor% +hwndEcnsHwnd,
	Gui, Add, Button, x+2 yp+1 h25 gECNsAdd, +
	Gui, Add, ListBox, xs-1 y+0 w%ListBoxW1% r6 c%ControlTxtColor% +AltSubmit hwndECNsListHwnd gECNs_Event,

	; --- Issue Description ---
	Gui, Add, Text, +BackgroundTrans  x20 y+25 +Section,Issue Description:
	Gui, Add, Edit, xs-1 y+5 w455 h235 c%ControlTxtColor% gIssueDesc_Change vIssueDesc hwndIssueDescHwnd, 
	

	; --- PSG REsponse ---
	Gui, Add, Text, +BackgroundTrans  x500 ys +Section,PSG Response:
	Gui, Add, Edit, xs-1 y+5 w460 h235 c%ControlTxtColor% gPSGResponse_Change vPsgResponse hwndPSGResponseHwnd,


	; --- Main Buttons ---
	gui, font, s11
	Gui, Add, button, x360 y+15 w120 h40 +Center +wrap hwndSaveToCwiHwnd, Save to CWI
	Gui, Add, Button, x+10 yp w120 h40 +Center +wrap hwndCopyToCBHwnd, Copy Description to Clipboard
	
	vX := GuiHeight - 25
	
	 ; --- Version ---
	 Gui, Add, Text, x15 y%vx% hwndVersionHwnd, %Version%
	 
	 
	; --- Show GUI ---
	Gui, Show, w%GuiWidth% h%GuiHeight%, %GuiTitle%
Return

 ;}
 
 
;{___  Event Handlers -----------------------------------------------------------------------------------------------



IssueSource_Event: ;{
	Gui, Submit, NoHide
	cur := %A_GuiControl%
	if (cur != psgDesc.IssueSource)
	{
		if InStr(cur, "Manufacturing")
		{
			psgDesc.issueSource := SubStr(cur, 1, 1) "M"
		}
		else if InStr(cur, "Procurement")
		{
			psgDesc.IssueSource := SubStr(cur, 1, 1) "P"
		}
		else if InStr(cur, "Product Line")
		{
			psgDesc.IssueSource := "PLM"
		}
		else
		{
			psgDesc.IssueSource := ""
		}
		_Changed := true
	}
;}
return



IssueType_Event:	;{
	Gui, submit, nohide
	psgDesc.Remove("IssueTypes")
	psgDesc.Insert("IssueTypes", {})
	loop, parse, %A_GuiControl%, |
		psgDesc.IssueTypes.Insert(A_LoopField)
	_Changed := true
;}
return



ShortDescription_Event:	;{
	Gui, Submit, NoHide
	sDesc := %A_GuiControl%
	if (sDesc != psg.ShortDescription)
	{
		psgDesc.ShortDescription := %A_GuiControl%
		_Changed := true
	}
;}
return



IssueDesc_Change:
PSGResponse_Change:	;{
	thisCtl := SubStr(Trim(A_ThisLabel), 1, -7) 
	thisCtlHwnd := thisCtl "Hwnd"
	GuiControlGet, thisValue,, % %thisCtlHwnd%
	psgDesc[thisCtl] := thisValue
	_Changed := true
;}
return




; -----------------------------------
; Add a value to one of the lists
; -----------------------------------
AssembliesAdd:
SubAssembliesAdd:
WorkOrdersAdd:
ECNsAdd:	
;{
	AddType := SubStr(Trim(A_ThisLabel), 1, -3)
	AddVar := AddType "Hwnd"
	ListVar := AddType "ListHwnd"
	GuiControlGet, AddValue,, % %AddVar%
	if (AddValue != "")
	{
		psgDesc[AddType].Insert(AddValue)
		; Add to listbox
		Control, Add, %AddValue%,, % "ahk_id " %ListVar%
		; Clear the input box
		GuiControl,, % %AddVar%,
	}
	_Changed := true
;}
return



; -----------------------------------
; Remove value from one of the lists
; -----------------------------------
Assemblies_Event:
SubAssemblies_Event:
WorkOrders_Event:
ECNs_Event:	;{
	if (A_GuiEvent = "DoubleClick")
	{
		DelType := SubStr(Trim(A_ThisLabel), 1, -6)
		DelListVar := DelType "ListHwnd"
		GuiControlGet, thisVal,, % %DelListVar%		
		psgDesc[DelType].Remove(thisVal)
		Control, Delete, %thisVal%,, % "ahk_id " %DelListVar%
	}
	_Changed := true
;}
return




ButtonSaveToCwi:	;{
	msgbox, 4404, PSG RTA Utility, !! NOTE !!`n`nThis will overwrite the current CWI description.`n`nWould you like to continue?
	
	;~ IfMsgBox, Yes
	;~ {
		newVal := PsgDesc.OutputDescription(Config.DescriptionTemplate)
		Clipboard := ""
		SplashImage,, w655 h175 B1 CWMaroon CTWhite FM14 FS12 WM800,`n`nPlease wait. Updating description......`n`n, PSG Rta Description Utility, 

		; Try to get the RTA ID
		run, cmd.exe /c `"%A_ScriptDir%\lib\RtaInfo.exe`" id %RtaNum% | clip,,Hide
		ClipWait, 2
		If (ErrorLevel || Instr(ClipBoard, "ERROR") || StrLen(Clipboard) < 5 || Instr(Clipboard, "Invalid"))
		{
			Clipboard:= ""
			Clipboard := newVal
			sleep 100
			SplashImage, off
			msgbox "Unable to get RTA ID...`n`nThe new description has been copied to your clipboard so that you may manually update the RTA."
			return
		}
		rtaID := Trim(Clipboard)
		sleep 100

		; Create an IE instance & wait for RTA modify page to load
		ie := ComObjCreate("InternetExplorer.Application")
		ie.Visible := 1
		ie.Navigate("http://cwiprod.corp.halliburton.com/cwi/CreateModifyRta.jsp?id=" Trim(rtaID, "`r`n"))
		loop
			sleep 250
		until (!ie.Busy)
		sleep 200
		loop
			sleep 250
		until (!ie.Busy)
		sleep 200
		
		
		; Set the description
		ie.document.getElementById("Description").value := newVal
		sleep 500
		
		
		
		;**** DEBUG *****
		;
		; Compare the IE description with the expected and see if it updated...
		if (Trim(newVal) != Trim(ie.document.getElementById("Description").value))
		{			
			msgbox, 4144, , The descriptions don't seem to match...
		}
		
		; TODO: Submit the form here. Need testing b4 implementing...
		;~ ie.document.forms(0).Submit()
		;~ sleep 250
		
		SplashImage, off
		
		msgbox, 324, PSG Rta Description Utility, Done!  The RTA's description has been updated. `n`nWould you like to open the RTA in CWI?`nPress <No> to simply exit the app.
		
		IfMsgBox, Yes
		{
			; Show the window & clean up resources
			ie.Visible := 1
		}
		else
			ie.Quit()
		
		ObjRelease(ie)		
	;~ }
;}
return

;}


;{___  Description Parsing -------------------------------------------------------------------------


ButtonSearch:
	gui, submit, nohide
	
	if (_Changed || issueDesc != "" || PsgResponse != "" || ShortDescription != "")
	{
		msgbox, 4148, Are You Sure?, This will overwrite all fields with the current CWI data!`n`nContinue and lose all unsaved changes?
		IfMsgBox, No
			return
	}
	ClearControls()
	Gui, Submit, nohide
	if (StrLen(RtaNum) < 6)
	{
		msgbox, 4144, RTA Creator, Invalid RTA Number...
		return
	}
	Clipboard := ""
	
	; -----------------------------------
	; Query the RTA description
	; -----------------------------------
	run, cmd /c `"%A_ScriptDir%\lib\RtaInfo.exe`" desc %RtaNum% | clip,,Hide
	ClipWait, 3
	If (ErrorLevel)
	{
		msgbox, 4160, RTA Creator, Unable to get data for RTA %RtaNum%
		return
	}
	Desc := Clipboard
	
	; Save output to txt for possible later use
	outFPath := Config.StdOut
	IfExist, %outFPath%
		FileDelete, %outFPath%
	SplitPath, outFPath, fName, fDir
	IfNotExist, %fDir%
		FileCreateDir, %fDir%
	FileAppend, %Desc%, %outFPath%
	
	
	
	if (RegExMatch(Desc, "i)HICPSG-(?P<Source>\w*?) - (?P<ShortDesc>.*?)?(?:[\r?\n|\r\n?])", issue))
	{	
		;{___  Existing RTA - Already PSG Formatted  ___}

		
		; Short Desc
		psgDesc.ShortDesc := IssueShortDesc
		GuiControl,, %ShortDescHwnd%, %IssueShortDesc%
		
		; Issue Source
		psgDesc.IssueSource := issueSource

		if (issueSource = "PLM")
		{
			issueSource := "Product Line Support"
		}
		else if (SubStr(issueSource, 1, 1) = "S")
		{	
			if (SubStr(issueSource, 0) = "M")
				issueSource := "Spring Manufacturing"
			else if (SubStr(issueSource, 0) = "P")
				issueSource := "Spring Procurement"
		}
		else if (SubStr(issueSource, 1, 1) = "L")
		{
			if (SubStr(issueSource, 0) = "M")
				issueSource := "Livingston Manufacturing"			
		}
		else if (SubStr(issueSource, 1, 1) = "O")
		{
			if (SubStr(issueSource, 0) = "M")
				issueSource := "Other Manufacturing"
			else if (SubStr(issueSource, 0) = "P")
				issueSource := "Other Procurement"
		}
		GuiControl, Choose, %IssueSourceHwnd%, %issueSource%
		
		StringReplace, Desc, Desc, %issueShortDesc%
		
		; Issue Types
		RegExMatch(Desc, "is)Issue Type.+?\ :(?:(?P<Types>.*?)(?:[\r?\n|\r\n?])\S)?", issue)		
		StringReplace, issueTypes, issueTypes, %A_Space%,, All
		loop, parse, issueTypes, CSV
		{
			if ((thisItm := Trim(Trim(A_LoopField), "`r`n")) != "")
			{				
				psgDesc.IssueTypes.Insert(thisItm)
				GuiControl, ChooseString, %IssueTypesHwnd%, % thisItm
			}
		}
		
		
		; Work Order
		RegExMatch(Desc, "is)Work Order.+?\ :(?:(?P<WorkOrders>.*?)[a-zA-Z])?", issue)
		StringReplace, issueWorkOrders, issueWorkOrders, %A_Space%,, All
		loop, parse, issueWorkOrders, CSV
			if ((thisItm := Trim(A_LoopField)) != "")
				psgDesc.WorkOrders.Insert(Trim(thisItm, "`r`n"))
		StringReplace, thisList, issueWorkOrders, `,, |, All
		GuiControl,, %WorkOrdersListHwnd%, %thisList%
		
		
		; Assemblies
		RegExMatch(Desc, "is)(?<!Sub|Sub-)(?:Ass|Com).+?\ :(?:(?P<Assemblies>.*?)[a-zA-Z])?", issue)		
		StringReplace, issueAssemblies, issueAssemblies, %A_Space%,, All
		loop, parse, issueAssemblies, CSV,`r`n
			if ((thisItm := Trim(A_LoopField)) != "")
				psgDesc.Assemblies.Insert(Trim(thisItm, "`r`n"))
		StringReplace, thisList, issueAssemblies, `,, |, All
		GuiControl,, %AssembliesListHwnd%, %thisList%
		
		
		; Sub-Assemblies
		RegExMatch(Desc, "is)(?<=Sub|Sub-)(?:Ass|Com).+?\ :(?:(?P<SubAssemblies>.*?)[a-zA-Z])?", issue)
		StringReplace, issueSubAssemblies, issueSubAssemblies, %A_Space%,, All
		loop, parse, issueSubAssemblies, CSV
			if ((thisItm := Trim(A_LoopField)) != "")
				psgDesc.SubAssemblies.Insert(Trim(thisItm, "`r`n"))
		StringReplace, thisList, issueSubAssemblies, `,, |, All
		GuiControl,, %SubAssembliesListHwnd%, %thisList%
		
		
		; ECNs
		RegExMatch(Desc, "im)ECN.+?\ :(?:(?P<ECNs>.*?)[a-zA-Z]?", issue)
		StringReplace, issueECNs, issueECNs, %A_Space%,, All
		loop, parse, issueECNs, CSV
			if ((thisItm := Trim(A_LoopField)) != "")
				psgDesc.ECNs.Insert(Trim(thisItm, "`r`n"))
		StringReplace, thisList, issueECNs, `,, |, All
		GuiControl,, %ECNsListHwnd%, %thisList%
		
		
		; PSG Response
		responsePos := RegExMatch(Desc, "ims)PSG RESPONSE:(?:[\r?\n|\r\n?])(?P<Response>.*)", issue)		
		psgDesc.PsgResponse := Trim(issueResponse, "`r`n")
		GuiControl,, %PsgResponseHwnd%, % Trim(issueResponse, "`r`n")
		
				
		; Issue Description
		StringTrimLeft, modDesc, Desc, % i
		tmpDesc := SubStr(desc, 1, responsePos - 2)
		issueDescription := Trim(SubStr(tmpDesc, instr(tmpDesc, "ISSUE DESCRIPTION:") + StrLen("ISSUE DESCRIPTION:")),"`r`n")
		psgDesc.IssueDesc := Trim(issueDescription, "`r`n")
		GuiControl,, %IssueDescHwnd%, %issueDescription%
						
	}
	else
	{	;
		; Existing NON-PSG RTA
		;
		psgDesc.IssueDesc := desc
		GuiControl,, %IssueDescHwnd%, %Desc%
	}
	
	_Changed := false
return

;}





/*!
	Function: ClearControls
		Clears values from all of the controls and re-initializes the RtaDescription object.  
		This function is generally used to handle a new RTA search when the form and/or data
		object already contain data.
*/
ClearControls()
{
	PsgDesc := ""
	PsgDesc := new PsgDescription()
	
	for index, ctlHwnd in Config.Lists.Controls.ChoiceType
	{
		GuiControl, Choose, % %ctlHwnd%, 0
	}
	
	for index, ctlHwnd in Config.Lists.Controls.ValueType
	{
		GuiControl,, % %ctlHwnd%,|
	}
}








/*!
	Function: PsgDescObjTemplate([obj])
		Returns an empty PsgDescription object wrapper.  
		An existing PsgDescriptino object instance may be passed to the
		function, cleared and re-initialized.

	Parameters:
		ByRef obj - (Optional) An existing PsgDescription object that is to be
					cleared, released and re-initialized.
*/
PsgDescObjTemplate(ByRef obj = "")
{
	if (IsObject(obj))
		ObjRelease(obj)
	
	obj := { IssueSource: "", ShortDesc: "", IssueDesc: "", PSGResponse: "", IssueTypes: {}, Assemblies: {}, SubAssemblies: {}, WorkOrders: {}, ECNs: {} }
	return obj
}




/*!
	Class: PsgDescription
		A simple object wrapper representing a "PSG Formatted" RTA description.  
*/
class CPsgDescription
{
	static IssueSource  := ""
	static ShortDesc 	:= ""
	static IssueDesc	:= ""
	static PsgResponse	:= ""
	
	
	/*!
		Constructor: ([rta])
			Initializes a new instance of the PsgDescription class.
		
		Parameters:	
			rta - (Optional) The RTA number whose data will be populated into
				  this object instance.  
				  This is not currently used, and has been implemented for possible
				  future uses such as storing/referencing multiple RTAs, etc.
	*/
	__New(rta = "")
	{
		this.RtaNum := rta
	}
	
	
	
	/*!
		Class: IssueTypes
			Object collection of the RTA's issue types.
	*/
	class CIssueTypes
	{
		
	}
	/*!
		End of class
	*/
		
	
	/*!
		Class: Assemblies
			Object collection of the RTA's affected assembly numbers.
	*/
	class CAssemblies
	{
		
	}
	/*!
		End of class
	*/
		
	
	/*!
		Class: SubAssemblies
			Object collection of the RTA's affected sub-assembly numbers.
	*/
	class CSubAssemblies
	{
		
	}
	/*!
		End of class
	*/
	
		
	/*!
		Class: WorkOrders
			Object collection of the RTA's affected work order numbers.
	*/
	class CWorkOrders
	{
		
	}
	/*!
		End of class
	*/
		
		
	IssueTypes 	  := new this.CIssueTypes()
	Assemblies 	  := new this.CAssemblies()
	SubAssemblies := new this.CSubAssemblies()
	WorkOrders 	  := new this.CWorkOrders()
	
	
	
	/*!
		Method: OutputDescription
			Returns a string value containing a formatted PSG description
			(description format defined in external config file), with the current
			PsgDescription object data values inserted where required.
		
		Parameters:
			template - A formatted template of a PSG description containing place-holders
					   where data values are to be inserted.  
					   The current template is stored in the app's config file, and is
					   accessible via the script's *Config* object at *Config.DescriptionTemplate*.
					   
		Returns:
			A formatted PSG description string based on the current data object.
	*/
	OutputDescription(template)
	{		
		StringReplace, v, template, <IssueSource>, % this.IssueSource
		StringReplace, v, v, <ShortDescription>, % this.ShortDescription
		StringReplace, v, v, <IssueTypes>, % this.GetDelimited(this.IssueTypes)
		StringReplace, v, v, <IssueDescription>, % this.IssueDesc
		StringReplace, v, v, <PsgResponse>, % this.PsgResponse
			
		StringReplace, v, v, <AssemblyNums>, % this.GetDelimited(this.Assemblies)
		StringReplace, v, v, <SubAssemblyNums>, % this.GetDelimited(this.SubAssemblies)
		StringReplace, v, v, <WorkOrders>, % this.GetDelimited(this.WorkOrders)
		StringReplace, v, v, <ECNNums>, % this.GetDelimited(this.ECNs)
		
		StringReplace, v, v, \n, `n, All
		
		return v
	}
	
	
	

	/*!
		Method: GetDelimited
			Parses the input variable (which can be a delimited string or an object/array)
			and returns a delimited string of its values.

		Parameters:
			obj 	 - The value whose contents will be parsed. This may be a string value
					   or an object/array.
			outDelim - (Optional) The string to be used as the output delimiter.
					   If not specified, default is a comma (,).
			inDelim  - (Optional) If the input is a string value, this specifies the delimiter
					   to parse it by. If not specifed, the default value is a new-line character (`n).
		Returns:
			Returns a delimited string containing all of the input object's values.			
	*/
	GetDelimited(obj, outDelim = ",", inDelim = "`n")
	{
		for ind, val in obj
		{
			if (count = 3)
			{
				listVar .= outDelim "`n                      " val
				count = 1
			}
			else
			{
				listVar .= (listVar ? outDelim : "") val
				count++
			}
		}
		ErrorLevel := count
		return listVar
	}



}
/*!
	End of class
*/



GuiContextMenu:
	
return



GuiSize:
	Anchor(IssueDescHwnd, "h")
	Anchor(PsgResponseHwnd, "h")
	Anchor(SaveToCwiHwnd, "y")
	Anchor(CopyToCBHwnd, "y")
return



#IfWinActive, PSG RTA Description Utility
~Enter::
~NumpadEnter::	
	ControlGetFocus, activeCtl, A
	if (activeCtl = "Edit1")	
		goto, ButtonSearch
return
#IfWinActive




GuiEscape:
GuiClose:
	if (!_Changed)
		ExitApp
	SetTimer, CustMBoxBtns, 50
	MsgBox, 262196, Exit Application?, Are you sure?	
	ifmsgbox, Yes
		Exitapp
return



CustMBoxBtns:
	if (!WinExist("Exit Application?"))
		return
	SetTimer, CustMBoxBtns, off
	ControlSetText, Button1, &Exit
	ControlSetText, Button2, &Return to App!
return



#Include <Anchor>